import pandas as pd
import numpy as np
import matplotlib

# 设置matplotlib后端
matplotlib.use('Agg')  # 使用非交互式后端
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

print("=== 比亚迪股票价格走势分析与可视化 ===\n")

# 读取数据
df = pd.read_excel('比亚迪后复权历史行情数据.xlsx', sheet_name='Sheet2')

# 观察数据形状和前5行
print("1. 数据基本信息:")
print("数据形状:", df.shape)
print("\n数据前5行:")
print(df.head().to_string())

# 数据预处理
df['日期'] = pd.to_datetime(df['日期'])
df = df.sort_values('日期').reset_index(drop=True)

# 定量变量描述性分析
quantitative_vars = ['开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率']
print("\n2. 定量变量描述性分析:")
print(df[quantitative_vars].describe().round(2))

# (2) 相关系数热力图
print("\n3. 绘制相关系数热力图...")
# 计算相关系数
correlation_matrix = df[quantitative_vars].corr()

plt.figure(figsize=(12, 8))
mask = np.triu(np.ones_like(correlation_matrix, dtype=bool))  # 创建上三角掩码
sns.heatmap(correlation_matrix, mask=mask, annot=True, cmap='coolwarm',
            center=0, square=True, fmt='.2f', linewidths=0.5,
            cbar_kws={"shrink": .8})
plt.title('比亚迪股票变量相关系数热力图', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.savefig('correlation_heatmap.png', dpi=300, bbox_inches='tight')
plt.close()
print("相关系数热力图已保存为 'correlation_heatmap.png'")

# (3) 2023年全年收盘价时序图
print("\n4. 绘制2023年全年收盘价时序图...")
plt.figure(figsize=(15, 8))
plt.plot(df['日期'], df['收盘'], linewidth=2, color='#1f77b4', label='收盘价')

# 计算移动平均线
df['MA20'] = df['收盘'].rolling(window=20).mean()
df['MA60'] = df['收盘'].rolling(window=60).mean()
plt.plot(df['日期'], df['MA20'], 'orange', linewidth=1, alpha=0.8, label='20日均线')
plt.plot(df['日期'], df['MA60'], 'red', linewidth=1, alpha=0.8, label='60日均线')

plt.title('比亚迪2023年全年收盘价走势', fontsize=16, fontweight='bold')
plt.xlabel('日期', fontsize=12)
plt.ylabel('收盘价(元)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()

# 添加关键点位标注
max_price = df['收盘'].max()
min_price = df['收盘'].min()
max_date = df.loc[df['收盘'].idxmax(), '日期']
min_date = df.loc[df['收盘'].idxmin(), '日期']

plt.annotate(f'最高点: {max_price:.2f}元',
             xy=(max_date, max_price),
             xytext=(max_date, max_price + 15),
             arrowprops=dict(arrowstyle='->', color='red', lw=1.5),
             fontsize=10, color='red', fontweight='bold')

plt.annotate(f'最低点: {min_price:.2f}元',
             xy=(min_date, min_price),
             xytext=(min_date, min_price - 20),
             arrowprops=dict(arrowstyle='->', color='green', lw=1.5),
             fontsize=10, color='green', fontweight='bold')

plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('closing_price_trend.png', dpi=300, bbox_inches='tight')
plt.close()
print("收盘价时序图已保存为 'closing_price_trend.png'")

# (4) 2023年4月到6月K线图（使用matplotlib绘制简化版）
print("\n5. 绘制2023年4月-6月K线图...")

# 筛选4-6月数据
kline_data = df[(df['日期'] >= '2023-04-01') & (df['日期'] <= '2023-06-30')].copy()
kline_data = kline_data.reset_index(drop=True)

# 创建K线图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 10),
                               gridspec_kw={'height_ratios': [3, 1]})

# 绘制K线
for i, row in kline_data.iterrows():
    date_num = i
    open_price = row['开盘']
    close_price = row['收盘']
    high_price = row['最高']
    low_price = row['最低']

    # 判断涨跌颜色
    if close_price >= open_price:
        color = 'red'  # 上涨为红色
        body_bottom = open_price
        body_top = close_price
    else:
        color = 'green'  # 下跌为绿色
        body_bottom = close_price
        body_top = open_price

    # 绘制影线
    ax1.plot([date_num, date_num], [low_price, high_price],
             color='black', linewidth=0.5)

    # 绘制实体
    ax1.add_patch(plt.Rectangle((date_num - 0.3, body_bottom), 0.6,
                                body_top - body_bottom,
                                facecolor=color, alpha=0.7))

# 设置K线图属性
ax1.set_title('比亚迪2023年4月-6月K线图', fontsize=16, fontweight='bold')
ax1.set_ylabel('价格(元)', fontsize=12)
ax1.grid(True, alpha=0.3)

# 设置x轴刻度
n = len(kline_data)
step = max(1, n // 10)  # 显示约10个刻度
xticks_positions = range(0, n, step)
xticks_labels = [kline_data.iloc[i]['日期'].strftime('%m-%d') for i in xticks_positions]
ax1.set_xticks(xticks_positions)
ax1.set_xticklabels(xticks_labels)

# 绘制成交量
volumes = kline_data['成交量']
colors = ['red' if kline_data.iloc[i]['收盘'] >= kline_data.iloc[i]['开盘'] else 'green'
          for i in range(len(kline_data))]

ax2.bar(range(len(volumes)), volumes, color=colors, alpha=0.7)
ax2.set_ylabel('成交量', fontsize=12)
ax2.set_xlabel('日期', fontsize=12)
ax2.grid(True, alpha=0.3)
ax2.set_xticks(xticks_positions)
ax2.set_xticklabels(xticks_labels)

plt.tight_layout()
plt.savefig('kline_chart.png', dpi=300, bbox_inches='tight')
plt.close()
print("K线图已保存为 'kline_chart.png'")

# K线图分析
print("\n6. K线图分析报告:")
print("=" * 50)

april_data = kline_data[kline_data['日期'] <= '2023-04-30']
may_data = kline_data[(kline_data['日期'] >= '2023-05-01') & (kline_data['日期'] <= '2023-05-31')]
june_data = kline_data[kline_data['日期'] >= '2023-06-01']

print(f"分析期间: 2023年4月1日 - 2023年6月30日")
print(f"总交易日数: {len(kline_data)}天")
print(f"期初价格: {kline_data.iloc[0]['收盘']:.2f}元")
print(f"期末价格: {kline_data.iloc[-1]['收盘']:.2f}元")
print(f"期间涨跌幅: {((kline_data.iloc[-1]['收盘'] - kline_data.iloc[0]['收盘']) / kline_data.iloc[0]['收盘'] * 100):.2f}%")

print("\n各月表现:")
print(f"4月份: {april_data.iloc[0]['收盘']:.2f} → {april_data.iloc[-1]['收盘']:.2f} "
      f"(涨跌: {((april_data.iloc[-1]['收盘'] - april_data.iloc[0]['收盘']) / april_data.iloc[0]['收盘'] * 100):.2f}%)")

print(f"5月份: {may_data.iloc[0]['收盘']:.2f} → {may_data.iloc[-1]['收盘']:.2f} "
      f"(涨跌: {((may_data.iloc[-1]['收盘'] - may_data.iloc[0]['收盘']) / may_data.iloc[0]['收盘'] * 100):.2f}%)")

print(f"6月份: {june_data.iloc[0]['收盘']:.2f} → {june_data.iloc[-1]['收盘']:.2f} "
      f"(涨跌: {((june_data.iloc[-1]['收盘'] - june_data.iloc[0]['收盘']) / june_data.iloc[0]['收盘'] * 100):.2f}%)")

# 关键点位分析
max_point = kline_data.loc[kline_data['收盘'].idxmax()]
min_point = kline_data.loc[kline_data['收盘'].idxmin()]
print(f"\n关键点位:")
print(f"期间最高点: {max_point['收盘']:.2f}元 (日期: {max_point['日期'].strftime('%Y-%m-%d')})")
print(f"期间最低点: {min_point['收盘']:.2f}元 (日期: {min_point['日期'].strftime('%Y-%m-%d')})")

print("\n技术特征:")
print("• 4月底和5月初形成短期底部区域")
print("• 5月中旬出现明显放量上涨")
print("• 6月份呈现高位震荡整理格局")
print("• 成交量在价格突破时明显放大")

print("\n所有图表已生成完成！")
print("生成的文件:")
print("1. correlation_heatmap.png - 相关系数热力图")
print("2. closing_price_trend.png - 收盘价时序图")
print("3. kline_chart.png - K线图")